home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ9203.ZIP / OOPASM.ZIP / LMATH.ASM < prev    next >
Assembly Source File  |  1990-05-08  |  5KB  |  306 lines

  1.     .MODEL    SMALL
  2.  
  3.     .CODE
  4.  
  5. ;---------------------------------------------------------
  6. ; __LngStg - Convert long integer to string.
  7. ;
  8. ; Entry -
  9. ;       DX,AX = Long integer.
  10. ;       ES:DI points to area for string.
  11. ;---------------------------------------------------------
  12.     Public  __LngStg
  13. __LngStg Proc   Near
  14.  
  15.     Push    Bp
  16.     Push    Di              ;BP+2
  17.     Push    Es              ;BP
  18.     Mov     Bp,Sp
  19.  
  20.     Mov     Si,Dx
  21.     Test    Dh,80h          ;Negative coming in ?
  22.     Jz      __LngStg0           ;Nope.
  23.     Not     Dx
  24.     Neg     Ax
  25.     Sbb     Dx,-1
  26. __LngStg0:
  27.     Sub     Bx,Bx
  28.     Push    Bx              ;Set end of string on stack.
  29. LongStg_Lp0:
  30.     Push    Si
  31.     Push    Dx
  32.     Push    Ax
  33.     Mov     Cx,0
  34.     Mov     Bx,10
  35.     Call    ___LDiv         ;Long/10.
  36.     Pop     Bx
  37.     Pop     Cx
  38.  
  39.     Push    Dx              ;Save next number to use.
  40.     Push    Ax
  41.     Push    Cx              ;Save old number.
  42.     Push    Bx
  43.     Mov     Cx,0
  44.     Mov     Bx,10
  45.     Call    ___LMul
  46.     Mov     Cx,Dx
  47.     Mov     Bx,Ax
  48.     Pop     Ax
  49.     Pop     Dx
  50.     Call    ___LSub         ;Find the remainder.
  51.     Mov     Bx,Ax
  52.     Pop     Ax              ;Get next number to use.
  53.     Pop     Dx
  54.     Pop     Si
  55.     Add     BL,'0'
  56.     Push    Bx              ;Save another digit.
  57.     Mov     Bx,Ax
  58.     Or      Bx,Dx           ;Result 0 yet ?
  59.     Jnz     LongStg_Lp0         ;Nope, so go back up.
  60. ;
  61. ; The number is broken down, so let's assemble a string.
  62. ;
  63.     Mov     Di,[Bp][2]          ;Load ES:DI with destination.
  64.     Mov     Es,[Bp]
  65.     Cld
  66.     Test    Si,8000h        ;Negative ?
  67.     Jz      LongStg_Pos         ;Nope, so jump.
  68.     Mov     AL,'-'
  69.     Stosb               ;Set minus sign into string.
  70. LongStg_Pos:
  71. LongStg_Lp1:
  72.     Pop     Ax
  73.     Stosb
  74.     Or      Al,Al
  75.     Jnz     LongStg_Lp1
  76.     Mov     Sp,Bp
  77.     Pop     Es
  78.     Pop     Di
  79.     Pop     Bp
  80.     Ret
  81.  
  82. __LngStg Endp
  83.  
  84.  
  85. ;------------------------- LOW LEVEL MATH ROUTINES ------------------------
  86. ;
  87. ;--------------------------
  88. ; ___Ladd - Add DX,AX to CX,BX, return DX,AX
  89. ; ___LSub - Sub CX,BX from DX,AX return DX,AX
  90. ;--------------------------
  91.     Public  ___Ladd,___LSub
  92. ___LSub  Proc    Near
  93.  
  94.     Push    Ax
  95.     Mov     Ax,0
  96.     Sub     Ax,Bx           ;Negate CX,BX.
  97.     Mov     Bx,Ax
  98.     Mov     Ax,0
  99.     Sbb     Ax,Cx
  100.     Mov     Cx,Ax
  101.     Pop     Ax
  102. ___Ladd:
  103.     Add     Ax,Bx
  104.     Adc     Dx,Cx
  105.     Ret
  106.  
  107. ___LSub  Endp
  108.  
  109.  
  110.  
  111.  
  112. ;--------------------------
  113. ; ___LMul - Long integer multiplier
  114. ;--------------------------
  115.     Public  ___LMul
  116. ___LMul  Proc    Near
  117.  
  118.     Push    Si
  119.     Push    Di
  120.     Push    Bp
  121.     Sub     Bp,Bp
  122. ;
  123. ; Check signs
  124. ;
  125.     Test    Dh,80h          ;Op A neg ?
  126.     Jz      ___LMul_PA
  127.     Not     Bp
  128.     Mov     Si,0
  129.     Sub     Si,Ax
  130.     Mov     Ax,Si
  131.     Mov     Si,0
  132.     Sbb     Si,Dx
  133.     Mov     Dx,Si
  134. ___LMul_PA:
  135.     Test    Ch,80h          ;Op B neg ?
  136.     Jz      ___LMul_PB
  137.     Not     Bp
  138.     Mov     Si,0
  139.     Sub     Si,Bx
  140.     Mov     Bx,Si
  141.     Mov     Si,0
  142.     Sbb     Si,Cx
  143.     Mov     Cx,Si
  144. ___LMul_PB:
  145.     Mov     Si,Dx
  146.     Mov     Di,Ax
  147.     Mul     Bx
  148.     Push    Ax
  149.     Push    Dx
  150.  
  151.     Mov     Ax,Si
  152.     Mul     Bx
  153.     Pop     Bx
  154.     Add     Ax,Bx
  155.     Adc     Dx,0
  156.     Push    Ax
  157.     Mov     Bx,Dx
  158.  
  159.     Mov     Ax,Di
  160.     Mul     Cx
  161.     Pop     Di
  162.     Add     Di,Ax
  163.     Push    Di
  164.     Mov     Di,0
  165.     Adc     Bx,Dx
  166.     Adc     Di,0
  167.  
  168.     Mov     Ax,Si
  169.     Mul     Cx
  170.     Add     Ax,Bx
  171.     Adc     Dx,Di
  172.     Pop     Cx
  173.     Pop     Bx
  174.  
  175.     Or      Ax,Dx
  176.     Mov     Ax,Bx
  177.     Mov     Dx,Cx
  178.     Pushf
  179.     Test    Bp,Bp
  180.     Jz      ___LMul_RP
  181.     Mov     Bx,0
  182.     Sub     Bx,Ax
  183.     Mov     Ax,Bx
  184.     Mov     Bx,0
  185.     Sbb     Bx,Dx
  186.     Mov     Dx,Bx
  187. ___LMul_RP:
  188.     Popf
  189.     Pop     Bp
  190.     Pop     Di
  191.     Pop     Si
  192.     Jz      ___LMul_Dne
  193.     Stc
  194. ___LMul_Dne:
  195.     Ret
  196.  
  197. ___LMul  Endp
  198.  
  199.  
  200.  
  201.  
  202. ;--------------------------
  203. ; ___LDiv - Divide
  204. ;
  205. ; OpA = DX,AX (DX=msw)
  206. ; OpB = CX,BX (CX=msw)
  207. ;
  208. ; A/B -> Destination (DX,AX - DX=msw)
  209. ;--------------------------
  210.     Public  ___LDiv
  211. ___LDiv   Proc    Near
  212.  
  213.     Push    Bp 
  214.     Sub     Sp,4 
  215.     Mov     Bp,Sp 
  216.     Mov     [Bp],Cx 
  217.     Or      Cx,Bx 
  218.     Jnz     __LD0           ;Jump if operand B is not 0.
  219.     Sub     Ax,Ax           ;If so, then return 0.
  220.     Mov     Dx,Ax
  221.     Jmp     __LD_Exit 
  222. __LD0:
  223.     Mov     [Bp+2],Dx 
  224.     Or      Dx,Ax 
  225.     Jnz     __LD1           ;Jump if operand A is not 0.
  226.     Jmp     __LD_Exit 
  227. __LD1:
  228.     Mov     Cx,[Bp] 
  229.     Mov     Dx,[Bp+2] 
  230.     Mov     Si,Dx 
  231.     Test    Si,Si
  232.     Jns     __LD2           ;Jump if op A is positive.
  233.     Not     Dx 
  234.     Neg     Ax 
  235.     Sbb     Dx,-1   
  236. __LD2:
  237.     Xor     Si,Cx 
  238.     Mov     [BP],Si         ;Save a sign flag.
  239.     Sub     Si,Si 
  240.     Test    Ch,Ch 
  241.     Jns     __LD3           ;Jump if op B is positive.
  242.     Not     Cx 
  243.     Neg     Bx 
  244.     Sbb     Cx,-1
  245. __LD3:
  246.     Jnz     __LD6 
  247.     Test    Bx,Bx 
  248.     Js      __LD6 
  249.     Mov     Di,20h
  250. __LD4:
  251.     Shl     Ax,1 
  252.     Rcl     Dx,1 
  253.     Rcl     Si,1 
  254.     Cmp     Si,Bx 
  255.     Jb      __LD5 
  256.     Sub     Si,Bx 
  257.     Inc     Ax 
  258. __LD5:
  259.     Dec     Di 
  260.     Jnz     __LD4 
  261.     Sub     Cx,Cx 
  262.     Mov     Bx,Si 
  263.     Jmp     __Lda 
  264. __LD6:
  265.     Mov     Di,0010h
  266. __LD7:
  267.     Shl     Ax,1 
  268.     Rcl     Dx,1 
  269.     Rcl     Si,1 
  270.     Cmp     Si,Cx 
  271.     Jb      __LD9 
  272.     Jnz     __LD8 
  273.     Cmp     Dx,Bx 
  274.     Jb      __LD9 
  275. __LD8:
  276.     Sub     Dx,Bx 
  277.     Sbb     Si,Cx 
  278.     Inc     Ax 
  279. __LD9:
  280.     Dec     Di 
  281.     Jnz     __LD7 
  282.     Mov     Cx,Si 
  283.     Mov     Bx,Dx 
  284.     Sub     Dx,Dx 
  285. __LDA:
  286.     Test Word Ptr [BP],8000h
  287.     Jz      __LDB 
  288.     Not     Dx 
  289.     Neg     Ax 
  290.     Sbb     Dx,-1
  291. __LDB:
  292.     Test Word Ptr [BP+2],8000h
  293.     Jz      __LD_Exit 
  294.     Not     Cx 
  295.     Neg     Bx 
  296.     Sbb     Cx,-1 
  297. __LD_Exit:
  298.     Add     Sp,4 
  299.     Pop     Bp 
  300.     Ret      
  301.  
  302. ___LDiv   Endp
  303.  
  304.  
  305.     END
  306.